package com.feather.common.db.wrapper;

import com.feather.common.db.Connector;
import com.feather.common.db.TransactConnector;
import com.feather.common.db.Transaction;
import com.feather.common.db.impl.NormalTransactionImpl;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author flogyin
 */
public class WrapperTransactConnector implements TransactConnector {
	protected static ThreadLocal<Connection>	THREAD_LOCAL	= new ThreadLocal<Connection>();
	protected Connector							connector;

	public WrapperTransactConnector(Connector connector) {
		this.connector = connector;
	}

	@Override
	public Connection getConnection() throws SQLException {
		Connection conn = THREAD_LOCAL.get();
		if (conn == null)
			return this.connector.getConnection();
		else
			return conn;
	}

	@Override
	public Transaction begin() throws SQLException {
		return begin(0);
	}

	@Override
	public Transaction begin(int isolationLevel) throws SQLException {
		Connection conn = this.connector.getConnection();
		try {
			conn.setAutoCommit(false);
			if (isolationLevel > 0)
				conn.setTransactionIsolation(isolationLevel);
		} catch (SQLException ex) {
			conn.close();
			throw ex;
		}
		Connection wrapper = new WrapperConnection(conn);
		Transaction transaction = new NormalTransactionImpl(THREAD_LOCAL, conn);
		THREAD_LOCAL.set(wrapper);
		return transaction;
	}

	// public class TransactProxyConnector implements InvocationHandler
	// {
	// private static ThreadLocal THREAD_LOCAL = new ThreadLocal();
	// private Connector connector;
	//
	//
	// private TransactProxyConnector(Connector c)
	// {
	// this.connector = c;
	// }
	//
	//
	// public static Connector bind(Connector c)
	// {
	// ClassLoader classLoader = c.getClass().getClassLoader();
	// Class[] interfaces = c.getClass().getInterfaces();
	// TransactProxyConnector proxy = new TransactProxyConnector(c);
	//
	// Object obj = Proxy.newProxyInstance(classLoader, interfaces, proxy);
	// return (Connector)obj;
	// }
	//
	//
	//
	// public Object invoke(Object proxy, Method method, Object[] args) throws
	// Throwable
	// {
	// Object connection = THREAD_LOCAL.get();
	// if (connection == null)
	// return method.invoke(this.connector, args); // 调用原始 getConnection()
	// else
	// return connection;
	// }
	//
	//
	// public Transaction begin() throws SQLException {
	// return begin(0);
	// }
	//
	// public Transaction begin(int isolationLevel) throws SQLException
	// {
	// Connection conn = this.connector.getConnection();
	// try {
	// conn.setAutoCommit(false);
	// if (isolationLevel > 0)
	// conn.setTransactionIsolation(isolationLevel);
	// } catch(SQLException ex) {
	// conn.close();
	// throw ex;
	// }
	// Connection wrapper = new WrapperConnectionImpl(conn);
	// Transaction transaction = new NormalTransactionImpl(THREAD_LOCAL, conn);
	// THREAD_LOCAL.set(wrapper);
	// return transaction;
	// }
	// }
}
